﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using WeddingEventManagement_API;
using WeddingEventManagementApp.Models;
using System.Web.Security;
using System.Text;
using System.Security.Cryptography;
using MvcSiteMapProvider;

namespace WeddingEventManagementApp.Controllers
{
    public class ClientController : BaseController
    {
        IClientManager clientManager;

        // Default Constructor
        public ClientController()
        {
            clientManager = new ClientManager();
        }

        //
        // GET: /Client/

        public ActionResult Index()
        {
            var isotopeClients = clientManager.GetIsotopeClients();

            foreach (var item in isotopeClients)
            {
                item.Gravatar = Utility.MD5Hash(item.Email.Trim().ToLower());
            }

            var model = new ClientMain_VM()
            {   
                RecentAddedClients = clientManager.GetMostRecentlyAddedClients(5),
                RecentViewedClients = clientManager.GetMostRecentlyViewedClients(5),
                IsotopeClients = isotopeClients
            };

            return View("Clients", model);
        }

        //
        // GET: /Client/Details/5
        //[MvcSiteMapNode(Title = "Details", ParentKey = "Clients")]
        public ActionResult Details(int id)
        {
            // get client by id
            var model = clientManager.GetClient(id);
            // update the LastViewed Property and push to the database
            model.LastViewed = DateTime.UtcNow;
            clientManager.UpdateClient(model, Utility.GetUserID(User.Identity.Name));

            // calculate gravatar hash
            ViewBag.Gravatar = Utility.MD5Hash(model.Email.ToLower().Trim());
            ViewBag.CreatorUserName = Membership.GetUser(model.CreatorUserID);

            List<ClientDetailInvoice_VM> invoices = new List<ClientDetailInvoice_VM>();
            foreach (Event e in model.Events)
            {
                foreach (Invoice inv in e.Invoices)
                {
                    invoices.Add(new ClientDetailInvoice_VM {
                        ClientID = id,
                        DueDate = inv.DueDate,
                        EventName = e.Title,
                        Total = new InvoiceManager().GetInvoiceTotal(inv.InvoiceID),
                        OutstandingBalance = new InvoiceManager().GetRemainingBalanceForInvoice(inv.InvoiceID),
                        InvoiceID = inv.InvoiceID
                    });
                }
            }
            
            ViewBag.invoices = invoices.OrderBy(i => i.DueDate).ToList();

            return View("ClientDetails", model);
        }

        //
        // GET: /Client/Create

        public ActionResult Create()
        {
            return View("AddClient");
        }

        //
        // POST: /Client/Create

        [HttpPost]
        public ActionResult Create(Client_VM model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    // create new client if modelstate is valid
                    var ClientID = clientManager.CreateClient
                    (
                        model.FirstName,
                        model.LastName,
                        model.Email,
                        model.Address,
                        model.City,
                        model.Province,
                        model.PostalCode,
                        model.Notes,
                        (
                            from phone in model.Phones
                            select new ClientPhone()
                            { 
                                Extension = phone.Extension,
                                LineNumber = phone.LineNumber,
                                Exchange = phone.Exchange,
                                AreaCode = phone.AreaCode,
                                PhoneNumberTypeID = (int)phone.PhoneNumberType
                            }
                        ).ToList(),
                        Utility.GetUserID(User.Identity.Name)
                    );

                    // redirect to newly created client page
                    return RedirectToAction("Details", new { id = ClientID });
                }
                catch (WeddingEventManagementException e)
                {
                    ModelState.AddModelError("", e.Message);
                }
            }

            // return view with error if problems arise

            return View("AddClient", model);
        }

        //
        // GET: /Client/Edit/5

        public ActionResult Edit(int id)
        {
            // get client
            var c = clientManager.GetClient(id);


            // Parse Province String to ENUM
            Province p;
            if(!Enum.TryParse(c.Provence, true, out p))
            {
                p = Province.ON; //if there is a problem default to Ontario
            }


            // translate to viewmodel
            var model = new Client_VM() 
            { 
                ClientID = c.ClientID, 
                FirstName = c.FirstName, 
                LastName = c.LastName, 
                Phones = (from phone in c.ClientPhones
                            select new ClientPhone_VM()
                            {
                                ID = phone.PhoneID,
                                PhoneNumberType = (PhoneNumberTypeEnum)phone.PhoneNumberTypeID,
                                AreaCode = phone.AreaCode,
                                Exchange = phone.Exchange,
                                Extension = phone.Extension,
                                LineNumber = phone.LineNumber
                            }
                         ).ToList(),
                Address = c.Address,
                City = c.City,
                PostalCode = c.PostalCode,
                Province = p,
                Email = c.Email,
                Notes = c.Notes
            };

            // calculate gravatar hash
            ViewBag.Gravatar = Utility.MD5Hash(model.Email.ToLower().Trim());

            return View(model);
        }

        //
        // POST: /Client/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, Client_VM model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    //map model to viewmodel
                    var c = clientManager.GetClient(id);
                    c.FirstName = model.FirstName;
                    c.LastName = model.LastName;
                    c.Email = model.Email;
                    c.Address = model.Address;
                    c.City = model.City;
                    c.PostalCode = model.PostalCode;
                    c.Provence = model.Province.ToString();
                    c.Notes = model.Notes;
                    c.ClientPhones = (from phone in model.Phones
                                      select new ClientPhone()
                                      {
                                          PhoneID = phone.ID != null ? phone.ID.Value : 0,
                                          AreaCode = phone.AreaCode,
                                          ClientID = model.ClientID,
                                          Extension = phone.Extension,
                                          LineNumber = phone.LineNumber,
                                          Exchange = phone.Exchange,
                                          PhoneNumberTypeID = Convert.ToInt32(phone.PhoneNumberType)
                                      }
                                      ).ToList();
                    c.LastUpdated = DateTime.UtcNow;

                    // push update
                    clientManager.UpdateClient(c, Utility.GetUserID(User.Identity.Name));

                    return RedirectToAction("Details", new { id = id });
                }
                catch(WeddingEventManagementException e)
                {
                    ModelState.AddModelError("", e.Message);
                }
            }

            // return view if error

            return View(model);
        }

        //
        // POST: /Client/Delete/5

        [HttpPost]
        public ActionResult Delete(int id)
        {
            clientManager.DeleteClient(id, Utility.GetUserID(User.Identity.Name));

            //todo check permissions on delete

            return RedirectToAction("Index");
        }


        public JsonResult DeletePhone(int? id)
        {
            bool result = false;

            // check is it's just an empty phone 
            if (id.HasValue)
            {
                if (id.Value == 0)
                {
                    result = true;
                }
                else
                {
                    try
                    {
                        result = clientManager.DeletePhoneNumber(id.Value);
                    }
                    catch (WeddingEventManagementException)
                    {
                        result = false;
                    }
                }
            }
            else
            {
                result = true;
            }

            // return successful delete or not
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        public JsonResult GetAllJson()
        {
            // get clients filtered by search term
            var data = new ClientManager().GetClients().OrderBy(c=> c.FirstName + "" + c.LastName);

            // tranlate model to viewmodel
            var newlist = new List<AutoCompleteClient_VM>();
            foreach (var client in data)
            {
                AutoCompleteClient_VM c = new AutoCompleteClient_VM();
                c.ID = client.ClientID;
                c.FirstName = client.FirstName;
                c.LastName = client.LastName;
                c.FullName = client.FirstName + " " + client.LastName;
                c.Gravatar = string.Format(@"http://www.gravatar.com/avatar/{0}?s={1}&d=identicon", Utility.MD5Hash(client.Email.ToLower().Trim()), "35");
                newlist.Add(c);
            }

            return Json(newlist, JsonRequestBehavior.AllowGet);
        }

        // Finds Client and returns as JSON
        public JsonResult Search(string term)
        {
            // get clients filtered by search term
            var data = new ClientManager().GetClients(term);

            // tranlate model to viewmodel
            var newlist = new List<AutoCompleteClient_VM>();
            foreach (var client in data)
            {
                AutoCompleteClient_VM c = new AutoCompleteClient_VM();
                c.ID = client.ClientID;
                c.FirstName = client.FirstName;
                c.LastName = client.LastName;
                c.FullName = client.FirstName + " " + client.LastName;
                c.Gravatar = string.Format(@"http://www.gravatar.com/avatar/{0}?s={1}&d=identicon", Utility.MD5Hash(client.Email.ToLower().Trim()), "35");
                newlist.Add(c);
            }

            return Json(newlist, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Returns all cities is database
        /// </summary>
        /// <returns></returns>
        public JsonResult Cities()
        {
            return Json(clientManager.GetUniqueCities(), JsonRequestBehavior.AllowGet);
        }

    }
}
